﻿//template < class T, // set::key_type/value_type
//	class Compare = less<T>, // set::key_compare/value_compare
//	class Alloc = allocator<T> // set::allocator_type
//> class set;

//// empty (1) ⽆参默认构造
//explicit set(const key_compare& comp = key_compare(),
//	const allocator_type& alloc = allocator_type());
//// range (2) 迭代器区间构造
//template <class InputIterator>
//set(InputIterator first, InputIterator last,
//	const key_compare& comp = key_compare(),
//	const allocator_type & = allocator_type());
//// copy (3) 拷⻉构造
//set(const set& x);
//// initializer list (5) initializer 列表构造
//set(initializer_list<value_type> il,
//	const key_compare& comp = key_compare(),
//	const allocator_type& alloc = allocator_type());
//// 迭代器是⼀个双向迭代器
//iterator->a bidirectional iterator to const value_type
//// 正向迭代器
//iterator begin();
//iterator end();
//// 反向迭代器
//reverse_iterator rbegin();
//reverse_iterator rend();

//Member types
//key_type->The first template parameter(T)
//value_type->The first template parameter(T)

//// 单个数据插⼊，如果已经存在则插⼊失败
//pair<iterator, bool> insert(const value_type& val);
//// 列表插⼊，已经在容器中存在的值不会插⼊
//void insert(initializer_list<value_type> il);
//// 迭代器区间插⼊，已经在容器中存在的值不会插⼊
//template <class InputIterator>
//void insert(InputIterator first, InputIterator last);
//// 查找val，返回val所在的迭代器，没有找到返回end()
//iterator find(const value_type& val);
//// 查找val，返回Val的个数
//size_type count(const value_type& val) const;
//// 删除⼀个迭代器位置的值
//iterator erase(const_iterator position);
//// 删除val，val不存在返回0，存在返回1
//size_type erase(const value_type& val);
//// 删除⼀段迭代器区间的值
//iterator erase(const_iterator first, const_iterator last);
//// 返回⼤于等于val位置的迭代器
//iterator lower_bound(const value_type& val) const;
//// 返回⼤于val位置的迭代器
//iterator upper_bound(const value_type& val) const;

//#include<iostream>
//#include<set>
//using namespace std;
//int main()
//{
//	// 去重+升序排序
//	set<int> s;
//	// 去重+降序排序（给⼀个⼤于的仿函数）
//	//set<int, greater<int>> s;
//	s.insert(5);
//	s.insert(2);
//	s.insert(7);
//	s.insert(5);
//	//set<int>::iterator it = s.begin();
//	auto it = s.begin();
//	while (it != s.end())
//	{   // error C3892: “it”: 不能给常量赋值
//        // *it = 1;
//		cout << *it << " ";
//		++it;
//	}
//	cout << endl;
//	// 插⼊⼀段initializer_list列表值，已经存在的值插⼊失败
//	s.insert({ 2,8,3,9 });
//	for (auto e : s)
//	{
//		cout << e << " ";
//	}
//	cout << endl;
//	set<string> strset = { "sort", "insert", "add" };
//	// 遍历string⽐较ascll码⼤⼩顺序遍历的
//	for (auto& e : strset)
//	{
//		cout << e << " ";
//	}
//	cout << endl;
//}
////运行结果：
////2 5 7
////2 3 5 7 8 9
////add insert sort

//#include<iostream>
//#include<set>
//using namespace std;
//int main()
//{
//	// 去重+升序排序
//	set<int> s = { 4,2,7,2,8,5,9 };
//	for (auto e : s)
//	{
//		cout << e << " ";
//	}
//	cout << endl;
//	// 删除最⼩值
//	s.erase(s.begin());
//	for (auto e : s)
//	{
//		cout << e << " ";
//	}
//	cout << endl;
//	// 直接删除x
//	int x;
//	cin >> x;
//	int num = s.erase(x);
//	if (num == 0)
//	{
//		cout << x << "不存在！" << endl;
//	}
//	for (auto e : s)
//	{
//		cout << e << " ";
//	}
//	cout << endl;
//	// 直接查找在利⽤迭代器删除x
//	cin >> x;
//	auto pos = s.find(x);
//	if (pos != s.end())
//	{
//		s.erase(pos);
//	}
//	else
//	{
//		cout << x << "不存在！" << endl;
//	}
//	for (auto e : s)
//	{
//		cout << e << " ";
//	}
//	cout << endl;
//	// 算法库的查找 O(N)
//	auto pos1 = find(s.begin(), s.end(), x);
//	// set⾃⾝实现的查找 O(logN)
//	auto pos2 = s.find(x);
//	// 利⽤count间接实现快速查找
//	cin >> x;
//	if (s.count(x))
//	{
//		cout << x << "在！" << endl;
//	}
//	else
//	{
//		cout << x << "不存在！" << endl;
//	}
//	return 0;
//}

//#include<iostream>
//#include<set>
//using namespace std;
//int main()
//{
//	set<int> myset;
//	for (int i = 1; i < 10; i++)
//		myset.insert(i * 10); // 10 20 30 40 50 60 70 80 90
//	for (auto e : myset)
//	{
//		cout << e << " ";
//	}
//	cout << endl;
//	// 实现查找到的[itlow,itup)包含[30, 60]区间
//	// 返回 >= 30
//	auto itlow = myset.lower_bound(30);
//	// 返回 > 60
//	auto itup = myset.upper_bound(60);
//	// 删除这段区间的值
//	myset.erase(itlow, itup);
//	for (auto e : myset)
//	{
//		cout << e << " ";
//	}
//	cout << endl;
//	return 0;
//}

//#include<iostream>
//#include<set>
//using namespace std;
//int main()
//{
//	// 相⽐set不同的是，multiset是排序，但是不去重
//	multiset<int> s = { 4,2,7,2,4,8,4,5,4,9 };
//	auto it = s.begin();
//	while (it != s.end())
//	{
//		cout << *it << " ";
//		++it;
//	}
//	cout << endl;
//	// 相⽐set不同的是，x可能会存在多个，find查找中序的第⼀个
//	int x;
//	cin >> x;
//	auto pos = s.find(x);
//	while (pos != s.end() && *pos == x)
//	{
//		cout << *pos << " ";
//		++pos;
//	}
//	cout << endl;
//	// 相⽐set不同的是，count会返回x的实际个数
//	cout << s.count(x) << endl;
//	// 相⽐set不同的是，erase给值时会删除所有的x
//	s.erase(x);
//	for (auto e : s)
//	{
//		cout << e << " ";
//	}
//	cout << endl;
//	return 0;
//}

//class Solution {
//public:
//    vector<int> intersection(vector<int>& nums1, vector<int>& nums2)
//    {
//        set<int> s1(nums1.begin(), nums1.end());// 1 2
//        set<int> s2(nums2.begin(), nums2.end());// 2
//        // 因为set遍历是有序的，有序值，依次⽐较
//        // ⼩的++，相等的就是交集
//        vector<int> ret;
//        auto it1 = s1.begin();
//        auto it2 = s2.begin();
//        while (it1 != s1.end() && it2 != s2.end())
//        {
//            if (*it1 < *it2)
//            {
//                it1++;
//            }
//            else if (*it1 > *it2)
//            {
//                it2++;
//            }
//            else
//            {
//                ret.push_back(*it1);
//                it1++;
//                it2++;
//            }
//        }
//        return ret;
//
//    }
//};


///**
// * Definition for singly-linked list.
// * struct ListNode {
// *     int val;
// *     ListNode *next;
// *     ListNode(int x) : val(x), next(NULL) {}
// * };
// */
//class Solution {
//public:
//    ListNode* detectCycle(ListNode* head)
//    {
//        set<ListNode*> s;
//        ListNode* cur = head;
//        while (cur)
//        {
//            auto ret = s.insert(cur);
//            if (ret.second == false)
//                return cur;
//            cur = cur->next;
//        }
//        return nullptr;
//    }
//};

////////////////////////////////////////////////////////////////////////////

//template < class Key, // map::key_type
//	class T, // map::mapped_type
//	class Compare = less<Key>, // map::key_compare
//	class Alloc = allocator<pair<const Key, T> > //
//	map::allocator_type
//> class map;


//typedef pair<const Key, T> value_type;
//template <class T1, class T2>
//struct pair
//{
//	typedef T1 first_type;
//	typedef T2 second_type;
//	T1 first;
//	T2 second;
//	pair() : first(T1()), second(T2())
//	{}
//	pair(const T1& a, const T2& b) : first(a), second(b)
//	{}
//	template<class U, class V>
//	pair(const pair<U, V>& pr) : first(pr.first), second(pr.second)
//	{}
//};
//template <class T1, class T2>
//inline pair<T1, T2> make_pair(T1 x, T2 y)
//{
//	return (pair<T1, T2>(x, y));
//}


//// empty (1) ⽆参默认构造
//explicit map(const key_compare& comp = key_compare(),
//	const allocator_type& alloc = allocator_type());
//// range (2) 迭代器区间构造
//template <class InputIterator>
//map(InputIterator first, InputIterator last,
//	const key_compare& comp = key_compare(),
//	const allocator_type & = allocator_type());
//// copy (3) 拷⻉构造
//map(const map& x);
//// initializer list (5) initializer 列表构造
//map(initializer_list<value_type> il,
//	const key_compare& comp = key_compare(),
//	const allocator_type& alloc = allocator_type());
//// 迭代器是⼀个双向迭代器
//iterator->a bidirectional iterator to const value_type
//// 正向迭代器
//iterator begin();
//iterator end();
//// 反向迭代器
//reverse_iterator rbegin();
//reverse_iterator rend();

//Member types
//key_type->The first template parameter(Key)
//mapped_type->The second template parameter(T)
//value_type->pair<const key_type, mapped_type>
//// 单个数据插⼊，如果已经key存在则插⼊失败,key存在相等value不相等也会插⼊失败
//pair<iterator, bool> insert(const value_type& val);
//// 列表插⼊，已经在容器中存在的值不会插⼊
//void insert(initializer_list<value_type> il);
//// 迭代器区间插⼊，已经在容器中存在的值不会插⼊
//template <class InputIterator>
//void insert(InputIterator first, InputIterator last);
//// 查找k，返回k所在的迭代器，没有找到返回end()
//iterator find(const key_type& k);
//// 查找k，返回k的个数
//size_type count(const key_type& k) const;
//// 删除⼀个迭代器位置的值
//iterator erase(const_iterator position);
//// 删除k，k存在返回0，存在返回1
//size_type erase(const key_type& k);
//// 删除⼀段迭代器区间的值
//iterator erase(const_iterator first, const_iterator last);
//// 返回⼤于等于k位置的迭代器
//iterator lower_bound(const key_type& k);
//// 返回⼤于k位置的迭代器
//const_iterator lower_bound(const key_type& k) const;

//Member types
//key_type->The first template parameter(Key)
//mapped_type->The second template parameter(T)
//value_type->pair<const key_type, mapped_type>
//// 查找k，返回k所在的迭代器，没有找到返回end()，如果找到了通过iterator可以修改key对应的
//mapped_type值
//iterator find(const key_type& k);
//// ⽂档中对insert返回值的说明
//// The single element versions (1) return a pair, with its member pair::first
////set to an iterator pointing to either the newly inserted element or to the
////element with an equivalent key in the map.The pair::second element in the pair
////is set to true if a new element was inserted or false if an equivalent key
////already existed.
//// insert插⼊⼀个pair<key, T>对象
//// 1、如果key已经在map中，插⼊失败，则返回⼀个pair<iterator,bool>对象，返回pair对象
////first是key所在结点的迭代器，second是false
//// 2、如果key不在在map中，插⼊成功，则返回⼀个pair<iterator,bool>对象，返回pair对象
////first是新插⼊key所在结点的迭代器，second是true
//// 也就是说⽆论插⼊成功还是失败，返回pair<iterator,bool>对象的first都会指向key所在的迭代器
//// 那么也就意味着insert插⼊失败时充当了查找的功能，正是因为这⼀点，insert可以⽤来实现operator[]
//// 需要注意的是这⾥有两个pair，不要混淆了，⼀个是map底层红⿊树节点中存的pair<key, T>，另
////⼀个是insert返回值pair < iterator, bool>
//pair<iterator, bool> insert(const value_type & val);
//mapped_type& operator[] (const key_type& k);
//// operator的内部实现
//mapped_type& operator[] (const key_type& k)
//{
//	    // 1、如果k不在map中，insert会插⼊k和mapped_type默认值，同时[]返回结点中存储
//	    //mapped_type值的引⽤，那么我们可以通过引⽤修改返映射值。所以[]具备了插⼊ + 修改功能
//		// 2、如果k在map中，insert会插⼊失败，但是insert返回pair对象的first是指向key结点的
//		//迭代器，返回值同时[]返回结点中存储mapped_type值的引⽤，所以[]具备了查找 + 修改的功能
//		pair<iterator, bool> ret = insert({ k, mapped_type() });
//	iterator it = ret.first;
//	return it->second;
//}

//#include<iostream>
//#include<map>
//using namespace std;
//int main()
//{
//	// initializer_list构造及迭代遍历
//	map<string, string> dict = { {"left", "左边"}, {"right", "右边"},
//	{"insert", "插⼊"},{ "string", "字符串" } };
//	//map<string, string>::iterator it = dict.begin();
//	auto it = dict.begin();
//	while (it != dict.end())
//	{
//		//cout << (*it).first <<":"<<(*it).second << endl;
//		// map的迭代基本都使⽤operator->,这⾥省略了⼀个->
//		// 第⼀个->是迭代器运算符重载，返回pair*，第⼆个箭头是结构指针解引⽤取pair数据
//		//cout << it.operator->()->first << ":" << it.operator->()-> second << endl;
//		cout << it->first << ":" << it->second << endl;
//		++it;
//	}
//	cout << endl;
//	// insert插⼊pair对象的4种⽅式，对⽐之下，最后⼀种最⽅便
//	pair<string, string> kv1("first", "第⼀个");
//	dict.insert(kv1);
//	dict.insert(pair<string, string>("second", "第⼆个"));
//	dict.insert(make_pair("sort", "排序"));
//	dict.insert({ "auto", "⾃动的" });
//	// "left"已经存在，插⼊失败
//	dict.insert({ "left", "左边，剩余" });
//	// 范围for遍历
//	for (const auto& e : dict)
//	{
//		cout << e.first << ":" << e.second << endl;
//	}
//	cout << endl;
//	string str;
//	while (cin >> str)
//	{
//		auto ret = dict.find(str);
//		if (ret != dict.end())
//		{
//			cout << "->" << ret->second << endl;
//		}
//		else
//		{
//			cout << "⽆此单词，请重新输⼊" << endl;
//		}
//	}
//	// erase等接⼝跟set完全类似，这⾥就不演⽰讲解了
//	return 0;
//}

//#include<iostream>
//#include<map>
//#include<string>
//using namespace std;
//int main()
//{   // 利⽤find和iterator修改功能，统计⽔果出现的次数
//	string arr[] = { "苹果", "西⽠", "苹果", "西⽠", "苹果", "苹果", "西⽠",
//	"苹果", "⾹蕉", "苹果", "⾹蕉" };
//	map<string, int> countMap;
//	for (const auto& str : arr)
//	{
//		// 先查找⽔果在不在map中
//		// 1、不在，说明⽔果第⼀次出现，则插⼊{⽔果, 1}
//		// 2、在，则查找到的节点中⽔果对应的次数++
//		auto ret = countMap.find(str);
//		if (ret == countMap.end())
//		{
//			countMap.insert({ str, 1 });
//		}
//		else
//		{
//			ret->second++;
//		}
//	}
//	for (const auto& e : countMap)
//	{
//		cout << e.first << ":" << e.second << endl;
//	}
//	cout << endl;
//	return 0;
//}

//#include<iostream>
//#include<map>
//#include<string>
//using namespace std;
//int main()
//{
//	// 利⽤[]插⼊+修改功能，巧妙实现统计⽔果出现的次数
//	string arr[] = { "苹果", "西⽠", "苹果", "西⽠", "苹果", "苹果", "西⽠",
//	"苹果", "⾹蕉", "苹果", "⾹蕉" };
//	map<string, int> countMap;
//	for (const auto& str : arr)
//	{
//		// []先查找⽔果在不在map中
//		// 1、不在，说明⽔果第⼀次出现，则插⼊{⽔果, 0}，同时返回次数的引⽤，++⼀下就变成1次了
//		// 2、在，则返回⽔果对应的次数++
//		countMap[str]++;
//	}
//	for (const auto& e : countMap)
//	{
//		cout << e.first << ":" << e.second << endl;
//	}
//	cout << endl;
//	return 0;
//}

#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
	map<string, string> dict;
	dict.insert(make_pair("sort", "排序"));
	// key不存在->插⼊ {"insert", string()}
	dict["insert"];
	// 插⼊+修改
	dict["left"] = "左边";
	// 修改
	dict["left"] = "左边、剩余";
	// key存在->查找
	cout << dict["left"] << endl;
	return 0;
}

class Solution {
public:
	struct Compare
	{
		bool operator()(const pair<string, int>& x, const pair<string, int>& y)
			const
		{
			// 要注意优先级队列底层是反的，⼤堆要实现⼩于⽐较，所以这⾥次数相等，想要字典
			序⼩的在前⾯要⽐较字典序⼤的为真
				return x.second < y.second || (x.second == y.second && x.first >
					y.first);
		}
	};
	vector<string> topKFrequent(vector<string>& words, int k) {
		map<string, int> countMap;
		for (auto& e : words)
		{
			countMap[e]++;
		}
		// 将map中的<单词，次数>放到priority_queue中，仿函数控制⼤堆，次数相同按照字典
		序规则排序
			priority_queue<pair<string, int>, vector<pair<string, int>>, Compare>
			p(countMap.begin(), countMap.end());
		vector<string> strV;
		for (int i = 0; i < k; ++i)
		{
			strV.push_back(p.top().first);
			p.pop();
		}
		return strV;
	}
};